"""
"""
import unittest as ut

import basicVdsTest as vdst
import vdsClient as vdsc
from vdsClient import BLANK_UUID
from storageConnectionTestUtils import eStorageType, disconnectFromStorage, connectToStorage, validateConnections, CONNECTIONS_OPTION_DEFAULT
from storageDomainTestUtils import eDomainClass, getDomainTargets, destroyDomainTargets
from confUtils import Validate
from enum import Enum

class MoveVolumeBetweenDomains(vdst.BasicVDSTest):
    #For convenience. I didn't put it in the base class because I didn't want to commit.
    mycfg = property(lambda self: self.cfg[self.__class__.__name__])
    @classmethod
    def getConfigTemplate(cls):
        return { cls.__name__ : {
                        "VdsUri1" : {"default" : "http://server:54321"},
                        "Connections" : {"default" : CONNECTIONS_OPTION_DEFAULT, "validator" : validateConnections},
                        "Domain1" : {"default" : "GUID, GUID", "validator" : Validate.list},
                        "StorageType1": {"default" : "nfs", "validator" : eStorageType.parse},
                        "DomainClass1" : {"default" : "data", "validator" : eDomainClass.parse},
                        "Domain2" : {"default" : "GUID, GUID", "validator" : Validate.list},
                        "StorageType2": {"default" : "nfs", "validator" : eStorageType.parse},
                        "DomainClass2" : {"default" : "data", "validator" : eDomainClass.parse},
                        "Domain3" : {"default" : "GUID, GUID", "validator" : Validate.list},
                        "StorageType3": {"default" : "nfs", "validator" : eStorageType.parse},
                        "DomainClass3" : {"default" : "data", "validator" : eDomainClass.parse},
                        "Domain4" : {"default" : "GUID, GUID", "validator" : Validate.list},
                        "StorageType4": {"default" : "nfs", "validator" : eStorageType.parse},
                        "DomainClass4" : {"default" : "data", "validator" : eDomainClass.parse},
                        "HostID1" : {"default" : 7, "validator" : Validate.int},
                        "Pool1Key" : {"default" : "NFSKEY"}
                    }
                }

    def setUp(self):
        #Setup client
        self.client = vdsc.VDSClient()
        self.client.setURI(self.mycfg["VdsUri1"])

        #Make sure env is clean
        succeeded, resp = self.assertVdscOK(self.client.getConnectedStoragePoolsList())
        self.assertTrue(len(resp['poollist']) == 0, "VDSM is connected to a pool. Dirty env. Bailing out.")

        #Handle storage configuration
        connectToStorage(self.client, self.mycfg["Connections"])
        self.domainTarget1, self.domainTarget2, self.domainTarget3, self.domainTarget4 = getDomainTargets(self.client, self.mycfg["Connections"],
            [self.mycfg["Domain1"], self.mycfg["Domain2"], self.mycfg["Domain3"], self.mycfg["Domain4"]])

        #setup test variables
        self.sdUUID1 = self.client.newUUID()
        self.sdUUID2 = self.client.newUUID()
        self.sdUUID3 = self.client.newUUID()
        self.sdUUID4 = self.client.newUUID()
        self.spUUID = self.client.newUUID()

        #Create the tmp domain
        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType1"], self.sdUUID1,
                "Storage Domain 1", self.domainTarget1, self.mycfg["DomainClass1"]
            )
        )

        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType2"], self.sdUUID2,
                "Storage Domain 2", self.domainTarget2, self.mycfg["DomainClass2"])
            )

        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType3"], self.sdUUID3,
                "Storage Domain 3", self.domainTarget3, self.mycfg["DomainClass3"])
            )

        self.assertVdscOK(
            self.client.createStorageDomain(self.mycfg["StorageType4"], self.sdUUID4,
                "Storage Domain 4", self.domainTarget4, self.mycfg["DomainClass4"])
            )

        #Create tmp pool
        self.assertVdscOK(
            self.client.createStoragePool(self.spUUID, "Swimming Pool", self.sdUUID1,
                [self.sdUUID1, self.sdUUID2, self.sdUUID3, self.sdUUID4], 1)
            )

        self.assertVdscOK(
            self.client.connectStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"])
            )

        taskid = self.assertVdscOK(self.client.spmStart(self.spUUID, -1, -1, -1, False))[1]['uuid']
        self.assertVdscTaskOK(self.client, taskid)

        self.assertVdscOK(
            self.client.activateStorageDomain(self.sdUUID1, self.spUUID)
        )

        self.assertVdscOK(
            self.client.activateStorageDomain(self.sdUUID2, self.spUUID)
        )

        self.assertVdscOK(
            self.client.activateStorageDomain(self.sdUUID3, self.spUUID)
        )

        self.assertVdscOK(
            self.client.activateStorageDomain(self.sdUUID4, self.spUUID)
        )

    def test(self):
        self.imgUUID = vdsc.VDSClient.newUUID()
        self.volUUID = vdsc.VDSClient.newUUID()
        self.vmUUID = vdsc.VDSClient.newUUID()

        volsize = 2048 #GB

        #Create base VM
        self.assertVdscOK(
            self.client.createVolume(self.sdUUID1, self.spUUID, self.imgUUID, volsize,
            vdsc.COW_FORMAT, vdsc.SPARSE_VOL, "DATA", self.volUUID, "Volly The Volume")
        )

        self.templateImgUUID = vdsc.VDSClient.newUUID()
        self.templateVolUUIDC1 = vdsc.VDSClient.newUUID()
        self.assertVdscOK(
            self.client.copyImage(self.sdUUID1, self.spUUID, self.vmUUID, self.imgUUID, self.volUUID,
            self.templateImgUUID, self.templateVolUUIDC1, "Shady Template", self.sdUUID1, vdsc.SHARED_VOL, vdsc.COW_FORMAT, vdsc.SPARSE_VOL)
        )

        self.assertVdscOK(
            self.client.copyImage(self.sdUUID1, self.spUUID, self.vmUUID, self.imgUUID, self.volUUID,
            self.templateImgUUID, self.templateVolUUIDC1, "Shady Template", self.sdUUID2, vdsc.SHARED_VOL, vdsc.COW_FORMAT, vdsc.SPARSE_VOL)
        )

        self.assertVdscOK(
            self.client.copyImage(self.sdUUID1, self.spUUID, self.vmUUID, self.imgUUID, self.volUUID,
            self.templateImgUUID, self.templateVolUUIDC1, "Shady Template", self.sdUUID3, vdsc.SHARED_VOL, vdsc.COW_FORMAT, vdsc.SPARSE_VOL)
        )

        self.assertVdscOK(
            self.client.copyImage(self.sdUUID1, self.spUUID, self.vmUUID, self.imgUUID, self.volUUID,
            self.templateImgUUID, self.templateVolUUIDC1, "Shady Template", self.sdUUID4, vdsc.SHARED_VOL, vdsc.COW_FORMAT, vdsc.SPARSE_VOL)
        )

        self.imgUUID2 = vdsc.VDSClient.newUUID()
        self.volUUID2 = vdsc.VDSClient.newUUID()

        self.assertVdscOK(
            self.client.createVolume(self.sdUUID1, self.spUUID, self.imgUUID2, volsize,
            vdsc.COW_FORMAT, vdsc.SPARSE_VOL, "DATA", self.volUUID2, "Volly The Volume", self.templateImgUUID, self.templateVolUUIDC1)
        )

        self.assertVdscOK(
            self.client.moveImage(self.spUUID, self.sdUUID1, self.sdUUID2, self.imgUUID2, self.vmUUID, 2, False, True)
            )

        self.assertVdscOK(
            self.client.moveImage(self.spUUID, self.sdUUID2, self.sdUUID3, self.imgUUID2, self.vmUUID, 2, False, True)
            )

        self.assertVdscOK(
            self.client.moveImage(self.spUUID, self.sdUUID3, self.sdUUID4, self.imgUUID2, self.vmUUID, 2, False, True)
            )

        self.assertVdscOK(
            self.client.moveImage(self.spUUID, self.sdUUID4, self.sdUUID3, self.imgUUID2, self.vmUUID, 2, False, True)
            )

        self.assertVdscOK(
            self.client.moveImage(self.spUUID, self.sdUUID3, self.sdUUID2, self.imgUUID2, self.vmUUID, 2, False, True)
            )

        self.assertVdscOK(
            self.client.moveImage(self.spUUID, self.sdUUID2, self.sdUUID1, self.imgUUID2, self.vmUUID, 2, False, True)
            )

    def tearDown(self):
        #Destroy pool
        self.assertVdscOK(
            self.client.deactivateStorageDomain(self.sdUUID4, self.spUUID, self.sdUUID1, -1)
        )
        self.assertVdscOK(
            self.client.deactivateStorageDomain(self.sdUUID3, self.spUUID, self.sdUUID1, -1)
        )
        self.assertVdscOK(
            self.client.deactivateStorageDomain(self.sdUUID2, self.spUUID, self.sdUUID1, -1)
        )
        self.assertVdscOK(
            self.client.deactivateStorageDomain(self.sdUUID1, self.spUUID, BLANK_UUID, -1)
        )

        self.assertVdscOK(self.client.destroyStoragePool(self.spUUID, self.mycfg["HostID1"], self.mycfg["Pool1Key"]))
        #format domain
        self.assertVdscOK(self.client.formatStorageDomain(self.sdUUID1, True))
        self.assertVdscOK(self.client.formatStorageDomain(self.sdUUID2, True))
        self.assertVdscOK(self.client.formatStorageDomain(self.sdUUID3, True))
        self.assertVdscOK(self.client.formatStorageDomain(self.sdUUID4, True))
        #disconnect
        destroyDomainTargets(self.client, [self.domainTarget1])
        disconnectFromStorage(self.client, self.mycfg["Connections"])

def suite():
    tests = {
        MoveVolumeBetweenDomains : ["test"]
    }

    resSuite = ut.TestSuite()
    for testcase, methods in tests.iteritems():
        resSuite.addTests(map(testcase, methods))

    return resSuite

validateConfig = lambda cfg : vdst.validateSuiteConfig(suite(), cfg)
